<?php

namespace Rjyst\ApiInvoke\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;

class InstallCommand extends Command
{
    protected $signature = 'api-invoke:install {--force : Force install without confirmation}';
    protected $description = 'Install RjYst API Invoke Package';

    public function handle()
    {
        $this->info('🚀 开始安装 RjYst API Invoke 组件库...');

        // 1. 更新路由文件
        $this->updateApiRoutes();

        // 2. 发布控制器文件
        $this->publishControllers();

        // 3. 发布枚举文件
        $this->publishEnums();

        // 4. 发布助手函数
        $this->publishHelpers();

        // 5. 发布工厂文件
        $this->publishFactory();

        // 6. 发布中间件文件
        $this->publishMiddleware();

        // 7. 更新异常处理器
        $this->updateExceptionHandler();

        // 8. 更新内核文件
        $this->updateKernel();

        $this->info('🎉 RjYst API Invoke 组件库安装完成！');
        $this->showNextSteps();
    }

    protected function updateApiRoutes()
    {
        $this->info('更新 API 路由文件...');

        $routeFile = base_path('routes/api.php');
        $targetContent = "Route::prefix('v1')->name('api.v1.')->group(function() {";

        if (File::exists($routeFile)) {
            $content = File::get($routeFile);

            // 检查是否已存在目标内容
            if (strpos($content, $targetContent) !== false) {
                $this->info('✅ API 路由已包含 v1 分组');
                return;
            }
        }

        // 覆盖路由文件
        $newRouteContent = '<?php

use Illuminate\Support\Facades\Route;

Route::prefix(\'v1\')->name(\'api.v1.\')->group(function() {

});
';

        File::put($routeFile, $newRouteContent);
        $this->info('✅ API 路由文件已更新');
    }

    protected function publishControllers()
    {
        $this->info('发布API控制器文件...');

        $controllerFile = app_path('Http/Controllers/Api/Controller.php');

        if (File::exists($controllerFile) && !$this->option('force')) {
            $this->info('✅ API Controller 已存在，跳过');
        } else {
            // 确保目录存在
            $controllerDir = app_path('Http/Controllers/Api');
            if (!File::isDirectory($controllerDir)) {
                File::makeDirectory($controllerDir, 0755, true);
            }

            $this->call('vendor:publish', ['--tag' => 'api-invoke-controllers', '--force' => $this->option('force')]);
            $this->info('✅ API Controller 创建完成');
        }
    }


    protected function publishEnums()
    {
        $this->info('发布枚举文件...');

        $responseEnum = app_path('Enums/Api/Response.php');

        if (File::exists($responseEnum) && !$this->option('force')) {
            $this->info('✅ Response 枚举已存在，跳过');
        } else {
            $this->call('vendor:publish', ['--tag' => 'api-invoke-enums', '--force' => $this->option('force')]);
            $this->info('✅ Response 枚举创建完成');
        }
    }

    protected function publishHelpers()
    {
        $this->info('发布助手函数...');

        $helperFile = app_path('helpers.php');

        if (File::exists($helperFile) && !$this->option('force')) {
            $this->info('✅ API 助手函数已存在，跳过');
        } else {
            $this->call('vendor:publish', ['--tag' => 'api-invoke-helpers', '--force' => $this->option('force')]);
            $this->info('✅ API 助手函数创建完成');
        }

        // 更新 composer.json 以自动加载助手函数
//        $this->updateComposerAutoload();
    }

    protected function publishFactory()
    {
        $this->info('发布工厂文件...');

        $factoryFile = app_path('Factory/ParseException.php');

        if (File::exists($factoryFile) && !$this->option('force')) {
            $this->info('✅ ParseException 工厂已存在，跳过');
        } else {
            $this->call('vendor:publish', ['--tag' => 'api-invoke-factory', '--force' => $this->option('force')]);
            $this->info('✅ ParseException 工厂创建完成');
        }
    }

    protected function publishMiddleware()
    {
        $this->info('发布中间件文件...');

        $middlewareFile = app_path('Http/Middleware/AcceptHeader.php');

        if (File::exists($middlewareFile) && !$this->option('force')) {
            $this->info('✅ AcceptHeader 中间件已存在，跳过');
        } else {
            $this->call('vendor:publish', ['--tag' => 'api-invoke-middleware', '--force' => $this->option('force')]);
            $this->info('✅ AcceptHeader 中间件创建完成');
        }
    }

    protected function updateExceptionHandler()
    {
        $this->info('更新异常处理器...');

        $handlerFile = app_path('Exceptions/Handler.php');

        if (!File::exists($handlerFile)) {
            $this->warn('⚠️  Handler.php 不存在，跳过更新');
            return;
        }

        $content = File::get($handlerFile);

        // 检查是否已包含 render 方法
        if (strpos($content, 'public function render($request, $e)') !== false) {
            $this->info('✅ Handler 已包含自定义 render 方法');
            return;
        }

        // 检查是否需要添加 use 语句
        $useStatements = [
            'use App\Enums\Api\Response as CustomResponse;',
            'use App\Factory\ParseException;',
            'use Illuminate\Auth\Access\AuthorizationException;',
            'use Illuminate\Auth\AuthenticationException;',
            'use Illuminate\Database\Eloquent\ModelNotFoundException;',
            'use Illuminate\Support\Str;',
            'use Illuminate\Validation\ValidationException;',
            'use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;',
            'use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;'
        ];

        foreach ($useStatements as $useStatement) {
            if (strpos($content, $useStatement) === false) {
                // 在最后一个 use 语句后添加新的 use 语句
                $content = preg_replace(
                    '/(use [^;]+;)(?!.*use)/s',
                    "$1\n$useStatement",
                    $content
                );
            }
        }

        // 在类的末尾（最后一个大括号前）添加 render 方法
        $renderMethod = $this->getRenderMethod();
        $lastBracePos = strrpos($content, '}');
        if ($lastBracePos !== false) {
            $content = substr_replace($content, "\n    " . $renderMethod . "\n}", $lastBracePos, 1);
        }

        File::put($handlerFile, $content);
        $this->info('✅ Handler 异常处理器更新完成');
    }

    protected function updateKernel()
    {
        $this->info('更新内核文件...');

        $kernelFile = app_path('Http/Kernel.php');

        if (!File::exists($kernelFile)) {
            $this->warn('⚠️  Kernel.php 不存在，跳过更新');
            return;
        }

        $content = File::get($kernelFile);

        // 检查是否已包含 AcceptHeader 中间件
        if (strpos($content, 'AcceptHeader::class') !== false) {
            $this->info('✅ Kernel 已包含 AcceptHeader 中间件');
            return;
        }

        // 添加 AcceptHeader 到 api 中间件组
        $content = str_replace(
            "'api' => [",
            "'api' => [\n            \\App\\Http\\Middleware\\AcceptHeader::class,",
            $content
        );

        // 更新 throttle 配置
        $content = str_replace(
            "\\Illuminate\\Routing\\Middleware\\ThrottleRequests::class.':api',",
            "'throttle:60,1',",
            $content
        );

        // 添加 middlewareAliases 如果不存在
        if (strpos($content, 'protected $middlewareAliases') === false) {
            $middlewareAliases = "
    /**
     * The application's middleware aliases.
     *
     * Aliases may be used instead of class names to conveniently assign middleware to routes and groups.
     *
     * @var array<string, class-string|string>
     */
    protected \$middlewareAliases = [
        'auth' => \\App\\Http\\Middleware\\Authenticate::class,
        'auth.basic' => \\Illuminate\\Auth\\Middleware\\AuthenticateWithBasicAuth::class,
        'auth.session' => \\Illuminate\\Session\\Middleware\\AuthenticateSession::class,
        'cache.headers' => \\Illuminate\\Http\\Middleware\\SetCacheHeaders::class,
        'can' => \\Illuminate\\Auth\\Middleware\\Authorize::class,
        'guest' => \\App\\Http\\Middleware\\RedirectIfAuthenticated::class,
        'password.confirm' => \\Illuminate\\Auth\\Middleware\\RequirePassword::class,
        'precognitive' => \\Illuminate\\Foundation\\Http\\Middleware\\HandlePrecognitiveRequests::class,
        'signed' => \\App\\Http\\Middleware\\ValidateSignature::class,
        'throttle' => \\Illuminate\\Routing\\Middleware\\ThrottleRequests::class,
        'verified' => \\Illuminate\\Auth\\Middleware\\EnsureEmailIsVerified::class,
    ];";

            // 在类的末尾添加 middlewareAliases
            $lastBracePos = strrpos($content, '}');
            if ($lastBracePos !== false) {
                $content = substr_replace($content, $middlewareAliases . "\n}", $lastBracePos, 1);
            }
        }

        File::put($kernelFile, $content);
        $this->info('✅ Kernel 内核文件更新完成');
    }

    protected function updateComposerAutoload()
    {
        $composerFile = base_path('composer.json');

        if (!File::exists($composerFile)) {
            return;
        }

        $composer = json_decode(File::get($composerFile), true);

        if (!isset($composer['autoload']['files'])) {
            $composer['autoload']['files'] = [];
        }

        $helperPath = 'app/helpers.php';

        if (!in_array($helperPath, $composer['autoload']['files'])) {
            $composer['autoload']['files'][] = $helperPath;

            File::put($composerFile, json_encode($composer, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
            $this->info('✅ composer.json 自动加载配置已更新');
            $this->warn('⚠️  请运行 composer dump-autoload 重新生成自动加载文件');
        }
    }

    protected function getRenderMethod()
    {
        return 'public function render($request, $e)
    {
        if ($e instanceof ModelNotFoundException) {
            return  apiResponse(CustomResponse::SYSTEM_ERROR->value,[],CustomResponse::SYSTEM_ERROR->response());
        }
        //非允许请求方式
        if ($e instanceof MethodNotAllowedHttpException) {
            return  apiResponse(CustomResponse::SYSTEM_REQUEST_ERROR->value,[],CustomResponse::SYSTEM_REQUEST_ERROR->response());
        }
        //验证失败
        if ($e instanceof ValidationException) {
            return  apiResponse(CustomResponse::SYSTEM_CHECK_ERROR->value,[],array_values($e->validator->getMessageBag()->toArray())[0][0]);
        }
        //验证token
        if ($e instanceof AuthenticationException || $e instanceof AuthorizationException) {
            return  apiResponse(CustomResponse::TOKEN_ERROR->value,[],CustomResponse::TOKEN_ERROR->response());
        }
        //这里是为了兼容其他的一些错误
        if (Str::length($e->getMessage()) > 1 && Str::length($e->getCode()) > 1) {
            return apiResponse($e->getCode(),[], $e->getMessage());
        }
        $result = ParseException::parseException($e);
        //这里判断的原因很简单 因为可能这个code没有按照规范声明
        if (is_array($result)) {
            return apiResponse($result[\'code\'], $result[\'message\']);
        }
        if ($e instanceof NotFoundHttpException) {
            return  apiResponse(CustomResponse::SYSTEM_NOT_FIND->value,[], CustomResponse::SYSTEM_NOT_FIND->response());
        }

        return parent::render($request, $e);
    }';
    }

    protected function showNextSteps()
    {
        $this->line('');
        $this->line('<fg=green>🎉 安装完成！功能已就绪：</>');
        $this->line('✅ API 路由结构已更新');
        $this->line('✅ 控制器基类已创建');
        $this->line('✅ API 响应枚举已创建');
        $this->line('✅ API 助手函数已创建');
        $this->line('✅ 异常解析工厂已创建');
        $this->line('✅ 中间件已创建');
        $this->line('✅ 异常处理器已更新');
        $this->line('✅ 内核文件已更新');
        $this->line('');
        $this->line('<fg=yellow>📋 可用功能：</>');
        $this->line('• API 路由分组: /api/v1/*');
        $this->line('• 统一响应格式: apiResponse() 助手函数');
        $this->line('• 自动异常处理和响应');
        $this->line('• Accept Header 自动设置为 application/json');
        $this->line('');
        $this->line('<fg=blue>🔧 下一步操作：</>');
        $this->line('• 运行 <fg=green>composer dump-autoload</> 重新生成自动加载');
        $this->line('• 在 routes/api.php 中添加你的 API 路由');
        $this->line('• 使用 apiResponse() 函数统一返回 JSON 响应');
        $this->line('');
        $this->line('<fg=red>卸载：</>');
        $this->line('如需卸载组件库，请运行: <fg=red>php artisan api-invoke:uninstall</>');
    }
}
